<?php 
/**
 * ... ...
 * ... ...
 *
 */ 


/**
 * 视图类 SessionView 
 *
 * @access public
 */
class JJ_SessionWindow
	//<<[UnmodifiableBlock.Start]::Extends And Implements::>>//
	extends JCAT_ViewGtk
	//<<[UnmodifiableBlock.End]::Extends And Implements::>>// 
{
	/**
	 * 取得 会话视图 享元
	 *
	 * @access	public
	 * @param	$aContact		JJ_Account
	 * @param	$aParent		JCAT_IViewContainer		视图的父对象(父视图 或 控制器)。注意：视图不应单独存在，必须有一个父对象！
	 * @return	SessionWindow
	 */
	static public function GetInstance(JJ_Account $aContact, JCAT_IViewContainer $aParent)
	{
		$sContact = strtolower($aContact) ;

		if( !isset(self::$arrInstances[$sContact]) )
		{
			self::$arrInstances[$sContact] = new self($aContact,$aParent) ;
			self::$arrInstances[$sContact]->SetInputingNotify(false) ;
		}
		
		return self::$arrInstances[$sContact] ;
	}

	/**
	 * 移除享元对象
	 *
	 * @access	public
	 * @param	$aContact		JJ_Account
	 * @static
	 * @return	void
	 */
	static public function RemoveInstance(JJ_Account $aContact)
	{
		$sContact = strtolower($aContact) ;
		unset(self::$arrInstances[$sContact]) ;
	}
	
	
	/**
	 * 构造函数 
	 *
	 * @access	protected
	 * @param	$aContact		JJ_Account
	 * @param	$aParent		JCAT_IViewContainer		视图的父对象(父视图 或 控制器)。注意：视图不应单独存在，必须有一个父对象！ 
	 * @return	void
	 */
	protected function JJ_SessionWindow(JJ_Account $aContact,JJ_MainController $aParent)
	{
		$this->aContact = $aContact ;
		
		// 调用父类构造函数 
		//<<[UnmodifiableBlock.Start]::Call Parent Construct::>>//
		$this->JCAT_ViewGtk('JJ_SessionWindow','template.JJ_SessionWindow.glade','JJ_SessionWindow',$aParent) ;
		//<<[UnmodifiableBlock.End]::Call Parent Construct::>>// 

		$this->Initialize() ;	
	}
	
	/**
	 * 初始化 视图 
	 *
	 * @access	protected
	 * @return	void
	 */
	protected function Initialize()
	{
		$this->Create() ;
		
		// 载入UI控件
		$sCurrentDirectory = dirname(__FILE__).'/' ;
		$this->AddUICtrl(JCAT_Package::ImportInstance($sCurrentDirectory.'Instances.UICtrl/instance.SessionInput.php',null,$this)) ;
		$this->AddUICtrl(new MessageHistory($this)) ;
		
		// 切分窗口 初始位置
	 	$wndPaned = $this->GetChildWidget('VPanedMessages');
	 	JCAT_ASSERT::ASSERT_INSTANCE($wndPaned,'GtkVPaned');
	 	$wndPaned->set_position(240) ;
	 	
	 	// 联系人名称
	 	$aContact = $this->GetContact() ;
	 	$sContactName = $aContact->GetUsername() ;
	 	$wndLabContact = $this->GetChildWidget('LabContact') ;
	 	$wndLabContact->set_label( "<b>{$sContactName}</b>" ) ;
	 	
	 	// 标题
	 	$this->GetWidget()->set_title(
	 		JCAT_Language::Sentence('正在与 %s 交谈 ...',$sContactName)
	 	) ;
	 	
	 	
	 	//$this->SetInputingNotify(false) ;
	 	
	 	// 输入框 变更
	 	//$wndInput = $this->GetChildWidget('SessionInput') ;
	 	//$aBuffer = $wndInput->get_buffer() ;
	 	//$aBuffer->connect('changed',array($this,'OnInputing')) ;
	 	
	 	// 表情窗口
	 	$this->aFaceWindow = new JJ_FaceWindow($this) ;
	 	
	}
	
	/**
	 * 取得 会话联系人
	 *
	 * @access	public
	 * @return	JJ_Account
	 */
	public function GetContact()
	{
		return $this->aContact ;
	}
	
	/**
	 * Description
	 *
	 * @access	public
	 * @return	JJ_MainController
	 */
	public function GetParentController()
	{
		return parent::GetParentController() ;
	}

	/**
	 * 响应 用户 关闭窗口
	 *
	 * @access	public
	 * @return	void
	 */
	public function OnCloseWindow()
	{
		$this->ShowView(false) ;
		return true ;
	}
	
	/**
	 * 响应 用户输入事件
	 *
	 * @access	public
	 * @return	void
	 */
	public function OnInputing(GtkTextBuffer $aBuffer)
	{
	}

	/**
	 * Description
	 *
	 * @access	public
	 * @return	void
	 */
	public function OnWindowKeyRelease(GtkWidget $wndWidget, GdkEvent $aEvent)
	{
		// 按 ESC 键关闭窗口 
		if( $aEvent->keyval==Gdk::KEY_Escape )
		{
			$this->OnCloseWindow() ;
		}
	}

	/**
	 * Description
	 *
	 * @access	public
	 * @return	void
	 */
	public function OnOpenSessionHistoryDialog()
	{
		// 显示历史记录 对话框
		$aMainController = $this->GetParentController() ;
		$aDialog = $aMainController->GetSessionHistoryDialog() ;
		$aDialog->ShowView(true) ;
		
		$aDialog->LoadSessionHistory($this->GetContact(),date('Y.m.d')) ;
	}
	
	/**
	 * 响应 输入框 失去焦点
	 *
	 * @access	public
	 * @return	void
	 */
	public function OnTextLostFocus()
	{
	}

	 /**
	  * 显示消息
	  *
	  * @access	public
	  * @param	$Author			JJ_Account,string
	  * @param	$sMessage			string
	  * @param	$bSend=true		bool
	  * @return	void
	  */
	public function DisplayMessage($Author,$sMessage,$bSend=true)
	{		
		JCAT_ASSERT::ASSERT_ISTHESE($Author,array('string','JJ_Account'))  ;
		if( is_string($Author) )
		{
			$sAuthor = $Author ;
		}
		
		else 
		{
			$sAuthor = $Author->GetUsername() ;
		}
		
		$sTime = date('y年n月j日 G:i:s') ;
		$sContent = "[{$sTime}]{$sAuthor}：\r\n-----------------\r\n{$sMessage}\r\n\r\n" ;
		
		// 整理		
		$sContent = str_replace('{%FaceDir%}',ROOT_PATH.'Resource/Face/',$sContent) ;
		
		$aMessageHistory = $this->GetUICtrl('MessageHistory') ;
		$aMessageHistory->AppendValue($sContent) ;
		
		// 保存记录
		$aMainController = $this->GetParentController() ;
		$aSessionHistoryDialog = $aMainController->GetSessionHistoryDialog() ;
		$aSessionHistoryDialog->Append($this->GetContact(),$sContent) ;

		// 移动到最下面
		$wndSessionHistoryScrolled = $this->GetChildWidget('SessionHistoryScrolled') ;
		$wndVAdjustment = $wndSessionHistoryScrolled->get_vadjustment() ;
		$wndVAdjustment->set_value( $wndVAdjustment->upper + $wndVAdjustment->page_size ) ;
	}
	
	public function SetInputingNotify($bInputing)
	{
	 	$wndInputingNotify = $this->GetChildWidget('InputingNotify') ;
	 	$wndInputingNotify->set_text( $bInputing? JCAT_Language::Sentence('  对方正在输入 ... ...'): '' ) ;
	}
	
	/**
	 * 发送
	 *
	 * @access	public
	 * @return	void
	 */
	public function OnSend()
	{		
		$sMessage = $this->GetUserInput() ;
		if( empty($sMessage) )
		{
			return '' ;
		}

		// 发送
		$aMainController = $this->GetParentController() ;
		JCAT_ASSERT::ASSERT_INSTANCE($aMainController,'JJ_MainController') ;
		$aMainController->SendMessage($this->GetContact(),$sMessage) ;

		// 显示
		$this->DisplayMessage('我',$sMessage);
	}
	
	/**
	 * 插入表情
	 *
	 * @access	public
	 * @return	void
	 */
	public function OnInsertFace()
	{
		$this->aFaceWindow->ShowView() ;
	}
	
	/**
	 * 取得用户输入
	 *
	 * @access	public
	 * @return	void
	 */
	public function GetUserInput()
	{
		// 换算 图像
		$wndSessionInput = $this->GetChildWidget('SessionInput') ;
		$aBuffSessHistory = $wndSessionInput->get_buffer() ;
		
		foreach ($this->arrImageAnchors as $arrAnchor)
		{
			// 已删除
			if($arrAnchor[0]->get_deleted())
			{
				continue ;
			}
			
			$sFaceFileName = basename($arrAnchor[1]) ;
			$aIter = $aBuffSessHistory->get_iter_at_child_anchor($arrAnchor[0]) ;
			$aBuffSessHistory->insert($aIter,"<img src='{%FaceDir%}{$sFaceFileName}' />") ;
		}

		// 取得内容
		$sMessage = $this->GetUICtrlExchangeData('SessionInput') ;
		$sMessage = trim($sMessage) ;

		// 清除
		$this->arrImageAnchors = array() ;
		$this->SetUICtrlExchangeData('SessionInput','') ;

		// 返回
		return $sMessage ;
	}

	 /**
	  * 打开会话记录窗口
	  *
	  * @access	public
	  * @return	void
	  */
	 public function OnOpenHistory()
	 {
	 	$aParent = $this->GetParent() ;
	 	$aParent->OpenSessionHistory() ;
	 }
	 
	 /**
	  * Description
	  *
	  * @access	public
	  * @return	void
	  */
	 public function OnKeyRelease(GtkWidget $wndWidget, GdkEvent $aEvent)
	 {
	 	// Shift + Enter
		if ( isset($this->bSendByEnterShift) and $this->bSendByEnterShift )
		{
			$this->OnSend() ;
			$this->bSendByEnterShift = false ;
	 	}
	 }

	 /**
	  * Description
	  *
	  * @access	public
	  * @return	void
	  */
	 public function OnKeyPress(GtkWidget $wndWidget, GdkEvent $aEvent)
	 {
	 	// Shift + Enter
		if ( $aEvent->keyval==Gdk::KEY_Return and ($aEvent->state & Gdk::SHIFT_MASK) )
		{
			$this->bSendByEnterShift = true ;
			return true ;
	 	}
	 }
	
	
	/**
	 * 打开 表情窗口
	 *
	 * @access	public
	 * @return	void
	 */
	public function ShowFaceWindow()
	{
		$this->aFaceWindow->ShowView() ;
	}
	
	/**
	 * 插入图像
	 *
	 * @access	public
	 * @return	void
	 */
	public function InsertImage( $sImagePath )
	{
		$wndSessionInput = $this->GetChildWidget('SessionInput') ;
		$aBuffSessHistory = $wndSessionInput->get_buffer() ;
		
        $aCursorPos = $aBuffSessHistory->get_mark('insert') ;
        $aIter = $aBuffSessHistory->get_iter_at_mark($aCursorPos) ;
        
        try{
        	$aImage = GtkImage::new_from_file($sImagePath);
        }
        catch (Exception $aException)
        {$aException ;
        	return ;
        }
        
        $aAnchor = $aBuffSessHistory->create_child_anchor($aIter);
        $wndSessionInput->add_child_at_anchor($aImage, $aAnchor);
        $aImage->show() ;
        
        $this->arrImageAnchors[] = array($aAnchor,$sImagePath) ;
	}
	
	/**
	 * 插入语句
	 *
	 * @access	public
	 * @return	void
	 */
	public function InsertWord($sWord)
	{
		$wndSessionInput = $this->GetChildWidget('SessionInput') ;
		$aBuffSessHistory = $wndSessionInput->get_buffer() ;

        $aBuffSessHistory->insert_at_cursor($sWord) ;
	}

	public function  PopupWordMenu()
	{
		$aManager = JCAT_Singleton::GetGlobalInstance('WordsManager') ;
		$aMenu = $aManager->CreateWordsMenu( array($this,'InsertWord') ) ;
		$aMenu->popup() ;
	}
	
	
	 /**
	  * 会话视图 享元
	  * 
	  * @access	private
	  * @var		array
	  */
	static private $arrInstances = array() ;

	/**
	 * Description
	 * 
	 * @access	private
	 * @var		array
	 */
	private $arrImageAnchors = array() ;
	
	/**
	 * 联系人账号
	 * 
	 * @access	private
	 * @var		JJ_Account
	 */
	private $aContact ;
	
	/**
	 * 本次会话消息
	 * 
	 * @access	private
	 * @var		string
	 */
	private $sThisSessionMessage = '' ;
	
	/**
	 * Description
	 * 
	 * @access	private
	 * @var		JJ_FaceWindow
	 */
	private $aFaceWindow ;
}

?><?
/**
 * [注意!!]
 *	以下内容由 JCAT PHP Toolbox 自动维护，手动更改的内容会被 JCAT PHP Toolbox 抹除，
 *	同时还可能破坏格式，导致 JCAT PHP Toolbox 无法正常读取。
 */
/*<<[UnmodifiableBlock.Start]::Coder Dialog Data::>>&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&//
<<{{DocumentClass:ViewGtkDoc}}>>
eCVEQSU5RFQlNUQlOEYlQTM2JTE0JTdEJUFGJUQ0JTFGJUIxJUJDdyUwOCVGOSU5OG4lQzlqJTI1JUMyRyU4QXdNJTAyJUQ4TjMlMkYlMTUlMTMlQUMlODQlRTAlODQlMTEwJUNBJUM3JTI4JUZGJUJEJUM3ZCUyNiVCQiVBQk4lQUIlQUElMEYlQzhwJTdEJTdEJTdDJUNFJTNEJUY3JTkyJUQ5JTdEJUZCJUE1JUIxJTg3
JUI2JUUxZW1mJThDMyVGQlclRkRtJTBEbEMlMTQlRjIlRTAlQUElQUNpJUEybCUyNyU4RDElODIlN0QlREIrJUFFJUMzJUZFJUQ0JTNCJUQzJUI2JUVDYjglQzlDJTI2d08lMkFrJUU1JTNDazclM0ElRkElMTElOTklRTYlQTYlREFJM1NSJTlBJUYzJUJBJURBJUNBVWslQ0UlN0YlOUYlRkYyZV9MJTkyJTNEJTNFJUNB
JURBTGRTJTNEJUQ3JTJCaSU3RSUwMzAlREIlRDclOTclQkJUNk1RJUVEJTE3JUM1JTNFJUFGJTBFd2slOTUlRTU3JTBFNCUyQiUxMCVDRiVENyVCMiUwRCVCRC4lMDYlQjIlM0YlQTQlQkYlMDUlQzMlRkQlMUIlQUVXJUQ0JTVEJUQwNiVBQyU4RSVERlUlRERNJTk4dSUwMyVEMCVFMSVFRjIlREUlMDQlREQlMEYlRkUl
OEIlQTAlQUVaJUIyMVd6JUJEJUZCJTBFJUYxJUVFaSVGMyVENCU1RCVGNCUxQkglODElOTElREMlQzklN0QlREIlODR6JTJCJUE4JUVBJTlEMSU4RSVDNiU5NyVFRU53UyVBOCVCQyU5NiU3Qm0lMDQlOEMlMjklRUMlMUUlNUUlMDYlREElOTElOTFtdCVCMCUxRCVDQ0clNUR0JUI3JUFEJTk1JTVCJUVEJTVCVEMlRDYl
NUUlQjUlRDIlM0JwYyVGRiUyNmp4SyVCQSU4MXYlMDl5ZzQ0JUREJURGJURCJUM2JUE3TyUyRiUyRjglRkIlQUMlMDl1JUY0JUVEJUJGJTAzXy4lOUYlM0YlRkYlRkMlOTN0JTg1JTFGJUYzRiVDNSVEQiVGOER4JUQ4JTIzJTNDJTk4JTdDLSU4NCUxQm1DJUM0JTgydFUlOTYlOEElOTYlMTElMTElQUVwaTlUMyUyRlYl
QzklRDZpJTkxJUU3JTExViVGNiUwOFMlMUUlM0QlOTMzJTJGJUY4MCUxNiUyMSVGNiVBOCU4QSVCQ0klOTElQTglQTVKJTNDJUFFZkwtJTA4cyVGQSU4NCVDNSUwNyVDMiVENlglQzMlMTElRDYlMUVfJTFDVTYlOERVJUNDJUI4JUEyJTJDVjMlMUVlJTg0JTA5TyVFMyUwMSUxNzlqSjglMUYlRTh3YU0yJUMyJUZEJUQz
JTgzJUNCRyVDOVQlMjklRTAlMEQlMDklRjM1JURGJTgxJUU2JUNDJTBCMSVBNSU3QiUwMiVFQyUwOSVDRSVBRXF2JTgyJUIzSyUyQnclRjklMjklMjklODQ3JUZCYyVGOSVEQyVERCVDQiVBMyUwOSVFMkclRUMlRkJpJTJBJTI2JTg5JUNCJTBGJUQ0byUxNCVFNSVBMSVBMiU5RSVERnElOTklRTl1SyVFNiU4NCVDNyVD
MCU4RSU3QyVDMnIlMTd3JUUwJUFFJTAwJTk4JTBGbiU5NiUwQSUyRiVEOSU4MiUyRnMlRjAlQUMlOEYlREMlMTUlNUUlN0MlMTIlMUUlRjUlMkIlNjAlOTQlMkElM0UlQzclQTglODlzJUE0ZSUwRlglMEUwJTFGJUVFJUExJTAzJURDJTdDJTBCWiVBMEclRDdYJTdGJTg3JTE2NCVFMSVEQiVFRiUxMy4lNUMlRjAlQjYl
MjRqSCVBMSUyNXJFJTEwJUVGcCUyRnMlOTAlQjMlMDQlNUV5JTQwJThFJTBGTmclQzIlMDglRjhQJUU4JTBGJTg3JTVDJTdCUiU0MEclQ0ElMEYlOTElMjglRDUlQ0MlRjdVJUMyJTI5JUZDJUQyWiUxQ0UlN0JLJTE1JUY1JUU4VSUxMyVGN1FnJUY4JUUzRSU4QyVCMCVDOCVBNyVEQSVBRiVCMiU4MV8lMjElQ0VBJTdG
JTE5JTkwJTE1eiUyMSUzQSVBMSUxRiU4MDclRUJ0JUFFJTgwJUM3JUExJTA5JTVFMiVGRjklM0UlRjElMTMlQjQlMDYlMDklQUZUJURDJTEzJTA0JTVDJTNDJUY0JThBJTFGJTk1JTE0NSU4MyU4RiUzRUclM0UlRUUlMjlpJTBEJUVFJTg3JUVCJTkzTyUwOSVEQiUwNDklQjglMjYlRUIlMEYlMUYlOEMlRjElQTUlQjAl
QUQlRjclREElQkYlM0YlQkElRkUlODclQThwZyU4RnolMEUlRkZtJTBBJUZBJUFGJTNGJUIyJUY3ZyVBMCUzRiVCNCVERSU5QiU4MSU3RkQlRkYlN0YlQTMlRDAlRTUxJUU3JUE0JTVCJUVBJTJCJURBJTA5JUU1JTE5RWglRDElRjhMTyUyQkslOTc1SCVCMXclRDYlQUQlQkYlMkMlNjAlRDElRUJIJUU4UiVDNWclQjEl
QjglOEUlQzMlQkElMkYlQ0FKJTk3JTE5JUVEJUI5JTFDJUE1JTI5JTFGJUNFWCUwOSVEQnQlMkIlQTIlOUQlQjZ4JTk4biUyQiU3RSVFOFolOUIlMjclOTMlMDUlQjAlQTglRTYlMEElQUJoJUNBJThGUSUyQSUwMiVFQXQlQTUlQkQlNUMlRkUlMDIlRTYlRTMlRjUlQzY!
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&<<[UnmodifiableBlock.End]::Coder Dialog Data::>>*/
?>